﻿using JWT;
using JWT.Algorithms;
using JWT.Exceptions;
using JWT.Serializers;
using Models;
using Newtonsoft.Json;
using SqlSugar;
using SqlSugar.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Web.Http;


namespace wnet.admin.wentcommon
{
    public class TokenAuthAttribute : AuthorizeAttribute
    {
        //重写基类的验证方式，加入我们自定义的Ticket验证
        public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            //url获取token
            var content = actionContext.Request.Properties["MS_HttpContext"] as HttpContextBase;
            var token = content.Request.Headers["Authorization"]; //自己加入在头部的名称
            if (!string.IsNullOrEmpty(token))
            {
                //解密用户ticket,并校验用户名密码是否匹配
                if (ValidateTicket(token))
                {
                    base.IsAuthorized(actionContext);
                }
                else
                {
                    HandleUnauthorizedRequest(actionContext);
                }
            }
            //如果取不到身份验证信息，并且不允许匿名访问，则返回未验证401
            else
            {
                var attributes = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();
                bool isAnonymous = attributes.Any(a => a is AllowAnonymousAttribute);
                if (isAnonymous) base.OnAuthorization(actionContext);
                else HandleUnauthorizedRequest(actionContext);
            }
        }

        //校验票据（数据库数据匹配）
        private bool ValidateTicket(string encryptToken)
        {
            //正常这里是用的token 来验证的
            bool flag = false;
            try
            {
                string token = encryptToken.Replace("Bearer ", "");
                string tokendata = tools.DecodeToken(token);
                Dictionary<string, object> dicdata = JsonConvert.DeserializeObject<Dictionary<string, object>>(tokendata);

                if (dicdata != null && dicdata.Count > 0)
                {
                    int UserId = dicdata["name"].ToString().ObjToInt();
                    ISqlSugarClient _sqlSugarClient = SqlSugarConfig.CreateClient();

                    var user = _sqlSugarClient.Queryable<sys_user>().Where(q => q.id == UserId).First();
                    if (user != null)
                    {
                        flag = true;
                    }
                }


            }
            catch (Exception ex)
            {

            }
            return flag;
        }
    }
    public class tools
    {
        static string secret = "35e63cc37033630a40c215a4369b2608";  //这个密钥以一般用加密过的 
        public static string DecodeToken(string strtoken)
        {
            try
            {
                IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
                IJsonSerializer serializer = new JsonNetSerializer();
                IDateTimeProvider provider = new UtcDateTimeProvider();
                IJwtValidator validator = new JwtValidator(serializer, provider);
                IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
                IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm);
                var json = decoder.Decode(strtoken, secret, verify: true);//token为之前生成的字符串
                return json;
            }
            catch (TokenExpiredException)
            {
                Console.WriteLine("Token has expired");  //过期
            }
            catch (SignatureVerificationException)
            {
                Console.WriteLine("Token has invalid signature");  //签名没有验证
            }
            return "";  // 根据你的json 里面解析出数据，然后去验证一下数据(当然这一步放到了验证中)
        }

        public static string Gettoken(string id)
        {
            IDateTimeProvider provider = new UtcDateTimeProvider();
            var now = provider.GetNow();
            var unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); // or use JwtValidator.UnixEpoch
            var secondsSinceEpoch = Math.Round((now - unixEpoch).TotalSeconds);
            int expnum = 1 * 60 * 60 * 24;
            var payload = new Dictionary<string, object>
            {
                   {"name", id },
                   {"exp",secondsSinceEpoch+expnum },  // 1000 秒过期时间，必须大于签发时间
                   {"jti","wenhuaju" }
             };
            Console.WriteLine(secondsSinceEpoch);
            IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
            IJsonSerializer serializer = new JsonNetSerializer();
            IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
            IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
            var token = encoder.Encode(payload, secret);
            return token;
        }
        public static string GetMD5Hash(string input)
        {
            // Create a new instance of the MD5CryptoServiceProvider object.
            using (MD5 md5Hasher = MD5.Create())
            {
                // Convert the input string to a byte array and compute the hash.
                byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));

                // Create a new StringBuilder to collect the bytes
                // and create a string.
                StringBuilder sBuilder = new StringBuilder();

                // Loop through each byte of the hashed data 
                // and format each one as a hexadecimal string.
                for (int i = 0; i < data.Length; i++)
                {
                    sBuilder.Append(data[i].ToString("x2"));
                }

                // Return the hexadecimal string.
                return sBuilder.ToString();
            }
        }

        public static int getuid()
        {

           
            try
            {

                var encryptToken = HttpContext.Current.Request.Headers["Authorization"]; //自己加入在头部的名称
                string token = encryptToken.Replace("Bearer ", "");
                string tokendata = tools.DecodeToken(token);
                Dictionary<string, object> dicdata = JsonConvert.DeserializeObject<Dictionary<string, object>>(tokendata);

                if (dicdata != null && dicdata.Count > 0)
                {
                    int UserId = dicdata["name"].ToString().ObjToInt();
                    return UserId;
                }

                return 0;
            }
            catch (Exception ex)
            {

            }
            return 0;
        }
    }
}